package com.dyz.model;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;

import com.dyz.view.FileExplorer;
import com.dyz.view.Widok;

/*
 * 
 */
public class Model {

	private List<AFaktura> list = new ArrayList<AFaktura>();
	/*
	 * przechowuje w pamieci spis wszystkich faktur z jednej firmy do
	 * pozniejszego wydrukowania
	 */
	private Set<String> adrSet = new TreeSet<String>();
	/*
	 * set adresow do comboboxa
	 */
	private Set<String> firmSet = new TreeSet<String>();// set firm do coboboxa
	private Map<String, String> map = new HashMap<String, String>();
	/*
	 * mapa do z firmami i adresami do podpowiedzi
	 */
	private String bierzacaSciezka; // D:\\asdasd.txt
	private String bierzacaNazwa; // asdasd

	public String getBierzacaNazwa() {
		return bierzacaNazwa;
	}

	private AFaktura fakt;
	private TreeSet<AFaktura> ts = new TreeSet<AFaktura>(new MyCompare());
	int nowyIndeksFakturPoPosortowaniuWTreeSet = 2;

	/* zapisuje kolejny rekord do bazy z ktorej pozniej czyta */
	public void save(AFaktura af) {

		FileWriter fw;
		File file = new File(bierzacaSciezka);
		
		if (file.exists()) {
			try {
				fw = new FileWriter(file, true);
				fw.write(af.toString() + System.lineSeparator());
				list.add(af);
				ts.add(af);
				System.out.println("przed zamknieciem, zapisal");
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			try {
				file.createNewFile();
				fw = new FileWriter(file, true);
				fw.write(af.toString() + System.lineSeparator());
				list.add(af);
				ts.add(af);
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/*
	 * tworzy nowa "Firme" do fakturowania, czyli nowy pliktxt
	 */
	public void makeFile(String nazwa, Widok w) {

		File file;

		updateAll();

		// TODO: file explorer z wyspecyfikowaniem sciezki zapisu

		// FileExplorer.createAndShowFileExplorer(w);

		if (nazwa.contains(".txt")) {
			file = new File(nazwa);
			bierzacaSciezka = nazwa;
			bierzacaNazwa = getFileName(nazwa);
			System.out.println("nazwa z stworzPlik: " + bierzacaSciezka);
			System.out.println("bierzacanazwa z stworzPlik: " + bierzacaNazwa);
		} else {
			bierzacaSciezka = nazwa + ".txt";
			bierzacaNazwa = getFileName(bierzacaSciezka);
			System.out.println("nazwa z stworzPlik: " + bierzacaSciezka);
			System.out.println("bierzacanazwa z stworzPlik: " + bierzacaNazwa);
			file = new File(nazwa + ".txt");
		}

		try {
			file.createNewFile();

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/*
	 * laduje do pamieci Firme(czyta z pliku txt)
	 */
	public void loadFile(String path) {

		updateAll();

		bierzacaSciezka = path;
		bierzacaNazwa = getFileName(path);
		int licznik = 1;

		try {
			Scanner sc = new Scanner(new File(path));
			Pattern p = Pattern.compile("\\s{2}");
			sc.useDelimiter(p);

			while (sc.hasNext()) {

				String d, nm, f, adr, o, rodzaj;
				float k1, k2;
				int v;

				sc.next();
				d = sc.next();
				nm = sc.next();
				f = sc.next();
				firmSet.add(f);
				adr = sc.next();
				adrSet.add(adr);
				map.put(f, adr);
				o = sc.next();
				k1 = sc.nextFloat();
				v = sc.nextInt();
				sc.next();
				sc.next();
				k2 = sc.nextFloat();
				rodzaj = sc.next();

				if (rodzaj.equalsIgnoreCase("koszt")) {
					fakt = new Koszty(nm, d, f, adr, o, v, k1, k2);
				} else if (rodzaj.equalsIgnoreCase("przychod")) {
					fakt = new Przychod(nm, d, f, adr, o, v, k1, k2);
				}

				list.add(fakt);
				ts.add(fakt);

				licznik++;
			}

			sc.close();
		} catch (Exception e) {
			System.out.println(e + " " + licznik);
			// lblNewLabel.setText("data input error\non line " + licznik);
		}

		for (AFaktura af : ts) {

			af.changeNumTo(nowyIndeksFakturPoPosortowaniuWTreeSet);
			System.out.println(af.toFormatString());
			nowyIndeksFakturPoPosortowaniuWTreeSet++;
		}

		nowyIndeksFakturPoPosortowaniuWTreeSet = 2;

	}

	public String getAdres(String firmy) {
		return map.get(firmy);
	}

	public void newPair(String firma, String adres) {

		map.put(firma, adres);
		firmSet.add(firma);
		adrSet.add(adres);
	}

	public boolean containsFirm(String s) {
		return firmSet.contains(s);
	}

	public boolean containsAdress(String s) {
		return adrSet.contains(s);
	}

	public void dodajFakture(AFaktura af) {
		list.add(af);
	}

	public Set<String> getFirms() {
		return firmSet;
	}

	public Set<String> getAdress() {
		return adrSet;
	}

	public List<AFaktura> getList() {
		return list;
	}

	/*
	 * zapisuje do nowego pliku sformatowana liste faktur wraz z posumowaniem
	 * miesiaca
	 */
	public void wydrukuj(int miesiac, String smiesiac) {

		System.out.println(calcPodsumowanie(miesiac));

		System.out.println("\\" + bierzacaNazwa + "_" + smiesiac + ".txt");
		File file = new File("\\" + bierzacaNazwa + "_" + smiesiac + ".txt");
		FileWriter fw;

		String s = String.format(
				"%6s. |%-10s| |%-20s| |%-20s| |%-50s| |%-20s| |%-10s|%-3s|%-10s|%-10s|%-10s|%s"
						+ System.lineSeparator(), "nr", "data d-m-y", "numer",
				"firma", "adres", "opis", "cenaNetto", "vat", "kwotaVat",
				"cenaBrutto", "cenaDod", "rodzajFaktury");

		System.out.println(s);

		try {
			file.createNewFile();
			fw = new FileWriter(file);
			fw.write(s);
			fw.write("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
					+ System.lineSeparator());
			fw.write(calcPodsumowanie(miesiac) + System.lineSeparator());
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/*
	 * oblicza wartosci podsumowania miesiaca
	 */
	private String calcPodsumowanie(int miesiac) {

		float cenaNettoMiesiacP = 0;
		float cenaNettoWylacznieP = 0;
		float cenaNettoWlacznieP = 0;

		float cenaDodMiesiac = 0;
		float cenaDodWylacznie = 0;
		float cenaDodWlacznie = 0;

		float cenaNettoMiesiacK = 0;
		float cenaNettoWylacznieK = 0;
		float cenaNettoWlacznieK = 0;

		String wypis = "";

		// cenaNettoMiesiacK = Koszty.getCenaNeto(miesiac-1);
		// cenaNettoMiesiacP = Przychod.getCenaNeto(miesiac-1);
		// cenaNettoWlacznieK += Koszty.getCenaNeto(miesiac-1);
		// cenaNettoWlacznieP += Przychod.getCenaNeto(miesiac-1);
		//
		// for (int m = 0; m < miesiac; m++) {
		// cenaNettoWylacznieK += Koszty.getCenaNeto(m);
		// cenaNettoWlacznieK += Koszty.getCenaNeto(m);
		// cenaNettoWylacznieP += Przychod.getCenaNeto(m);
		// cenaNettoWlacznieP += Przychod.getCenaNeto(m);
		// }
		//
		// if (!(miesiac == 1)) {
		// cenaNettoWlacznieK += Koszty.getCenaNeto(miesiac-1);
		// cenaNettoWlacznieP += Przychod.getCenaNeto(miesiac-1);
		// }

		if (miesiac == 1)
			wypis = wypis.concat(String.format(
					"%6s. |%10s| |%-20s| |%-20s| |%-50s| |%-20s| |%-10s|%-3s|%-10s|%-10s|%-10s|%s"
							+ System.lineSeparator(), "1", "01-01-2013", "",
					"", "", "BilansOtwarcia", "", "", "", "", "", ""));

		// for (AFaktura af : ts) {
		// if (af.getMonth() == miesiac) {
		// wypis = wypis.concat(af.toFormatString()
		// + System.lineSeparator());
		// }
		// }

		for (int i = 1; i <= miesiac; i++) {
			for (AFaktura af : ts) {

				af.changeNumTo(nowyIndeksFakturPoPosortowaniuWTreeSet);
				System.out.println(af.toFormatString());
				nowyIndeksFakturPoPosortowaniuWTreeSet++;

				if (af.getMonth() == i) {

					if (af.isPrzychod()) {
						cenaNettoWlacznieP += af.getCenaNetto();
						cenaDodWlacznie += af.getCenaDod();
						if (i == miesiac) {
							cenaNettoMiesiacP += af.getCenaNetto();
							cenaDodMiesiac += af.getCenaDod();
							// System.out.println(af.toFormatString());
							wypis = wypis.concat(af.toFormatString()
									+ System.lineSeparator());
						}
					} else if (!af.isPrzychod()) {
						cenaNettoWlacznieK += af.getCenaNetto();

						if (i == miesiac) {

							cenaNettoMiesiacK += af.getCenaNetto();

							// System.out.println(af.toFormatString());
							wypis = wypis.concat(af.toFormatString()
									+ System.lineSeparator());

						}// commit chuj
					}
				}
			}

			// System.out.println(i + 1 + "------------------------");
		}
		nowyIndeksFakturPoPosortowaniuWTreeSet = 2;

		cenaDodWylacznie = cenaDodWlacznie - cenaDodMiesiac;
		cenaNettoWylacznieP = cenaNettoWlacznieP - cenaNettoMiesiacP;
		cenaNettoWylacznieK = cenaNettoWlacznieK - cenaNettoMiesiacK;

		float cenaSumaMiesiac = cenaNettoMiesiacP + cenaDodMiesiac;
		float cenaSumaWylacznie = cenaNettoWylacznieP + cenaDodWylacznie;
		float cenaSumaWlacznie = cenaNettoWlacznieP + cenaDodWlacznie;
		//
		// System.out.printf("%.2f %.2f %.2f %.2f\n", cenaNettoMiesiacP,
		// cenaDodMiesiac, cenaSumaMiesiac, cenaNettoMiesiacK);
		// System.out.printf("%.2f %.2f %.2f %.2f\n", cenaNettoWylacznieP,
		// cenaDodWylacznie, cenaSumaWylacznie, cenaNettoWylacznieK);
		// System.out.printf("%.2f %.2f %.2f %.2f\n", cenaNettoWlacznieP,
		// cenaDodWlacznie, cenaSumaWlacznie, cenaNettoWlacznieK);
		return String.format("%s %.2f %.2f %.2f %.2f" + System.lineSeparator()
				+ "%.2f %.2f %.2f %.2f" + System.lineSeparator()
				+ "%.2f %.2f %.2f %.2f" + System.lineSeparator(), wypis,
				cenaNettoMiesiacP, cenaDodMiesiac, cenaSumaMiesiac,
				cenaNettoMiesiacK, cenaNettoWylacznieP, cenaDodWylacznie,
				cenaSumaWylacznie, cenaNettoWylacznieK, cenaNettoWlacznieP,
				cenaDodWlacznie, cenaSumaWlacznie, cenaNettoWlacznieK);
	}

	/*
	 * czysci wszystkie listy,ustawia na zero licznik faktur
	 */
	private void updateAll() {

		adrSet.removeAll(adrSet);
		firmSet.removeAll(firmSet);
		map.remove(map.keySet());
		AFaktura.zerujFaktury();
		list.removeAll(list);
		ts.removeAll(ts);
		nowyIndeksFakturPoPosortowaniuWTreeSet = 2;
	}

	public String getFileName(String s) {
		Path p = Paths.get(s);
		String path = p.getFileName().toString();
		return path.substring(0, path.length() - 4);

	}

}
